package com.dy.yunying.biz.controller.datacenter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.dy.yunying.api.constant.Constant;
import com.dy.yunying.api.constant.RetentionKpiEnum;
import com.dy.yunying.api.datacenter.dto.RetentionDto;
import com.dy.yunying.api.datacenter.export.AdExportRecoveryVo;
import com.dy.yunying.api.datacenter.export.ExportRetentionVo;
import com.dy.yunying.biz.service.datacenter.RetentionService;
import com.dy.yunying.biz.utils.DateUtils;
import com.dy.yunying.biz.utils.ExportAlibabaUtils;
import com.dy.yunying.biz.utils.ExportUtils;
import com.dy.yunying.biz.utils.MapUtils;
import com.pig4cloud.pig.common.core.exception.BusinessException;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 留存报表相关接口
 *
 * @ClassName RetentionController
 * @Description done
 * @Author nieml
 * @Time 2021/6/21 15:53
 * @Version 1.0
 **/

@RestController("retention")
@RequestMapping("/dataCenter/retention")
@Slf4j
public class RetentionController {

	private static final String[] RETENTION_KEYS = {"retention2", "retention3", "retention4", "retention5", "retention6", "retention7", "retention8", "retention9", "retention10", "retention11", "retention12", "retention13", "retention14", "retention15", "retention16", "retention17", "retention18", "retention19", "retention20", "retention21", "retention22", "retention23", "retention24", "retention25", "retention26", "retention27", "retention28", "retention29", "retention30"};

	@Autowired
	private RetentionService retentionService;

	/**
	 * 留存报表总数
	 *
	 * @param req
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/count")
	public R countDataTotal(@Valid @RequestBody RetentionDto req) {
		try {
			//校验参数
			Long sTime = req.getRsTime();
			Long eTime = req.getReTime();
			if (Objects.isNull(sTime) || sTime <= 0) {
				throw new Exception("请选择起始日期");
			}
			if (Objects.isNull(eTime) || eTime <= 0) {
				throw new Exception("请选择结束日期");
			}

			String retentionKpi = req.getRetentionKpi();
			if (StringUtils.isBlank(retentionKpi) || (!RetentionKpiEnum.REG.getType().equals(retentionKpi) && !RetentionKpiEnum.PAY.getType().equals(retentionKpi))) {
				throw new Exception("请选择指标");
			}
			return retentionService.countDataTotal(req);
		} catch (Exception e) {
			log.error("selectRetentionData:{}", e);
			return R.failed(e.getMessage());
		}
	}


	/**
	 * 留存报表分页列表
	 *
	 * @param req
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/getRetention")
	public R selectRetentionData(@Valid @RequestBody RetentionDto req) {
		try {
			//校验参数
			Long sTime = req.getRsTime();
			Long eTime = req.getReTime();
			if (Objects.isNull(sTime) || sTime <= 0) {
				throw new Exception("请选择起始日期");
			}
			if (Objects.isNull(eTime) || eTime <= 0) {
				throw new Exception("请选择结束日期");
			}

			String retentionKpi = req.getRetentionKpi();
			if (StringUtils.isBlank(retentionKpi) || (!RetentionKpiEnum.REG.getType().equals(retentionKpi) && !RetentionKpiEnum.PAY.getType().equals(retentionKpi))) {
				throw new Exception("请选择指标");
			}
			return retentionService.selectRetentionData(req);
		} catch (Exception e) {
			log.error("selectRetentionData:{}", e);
			return R.failed(e.getMessage());
		}
	}

	/**
	 * 留存报表导出
	 *
	 * @param req
	 * @return
	 */
	@ResponseExcel(name = "留存报表导出", sheet = "留存报表导出")
	@RequestMapping("/export")
	public R export(@Valid @RequestBody RetentionDto req, HttpServletResponse response, HttpServletRequest request) {
		try {
			List resultList = new ArrayList();
			String sheetName = "留存报表";
			// 临时采用循环查询解决数据过大的问题
			Long current = 1L;
			while (true) {
				req.setSize(1500L);
				req.setCurrent(current);
				List tmpList = (List) retentionService.selectRetentionData(req).getData();
				if (CollectionUtils.isEmpty(tmpList)) {
					break;
				}
				resultList.addAll(tmpList);
				current++;
			}
			// 查询汇总行-汇总只有一条
			if (StringUtils.isNotBlank(req.getQueryColumn()) || 4 != req.getCycleType()) {
				req.setSize(1L);
				req.setCurrent(1L);
				req.setCycleType(4);
				req.setQueryColumn(Constant.EMPTTYSTR);
				R collect = retentionService.selectRetentionData(req);
				resultList.addAll((List) collect.getData());
			}

			String fileName = URLEncoder.encode("留存报表-"+ DateUtils.getCurrentTimeNoUnderline(), "UTF-8").replaceAll("\\+", "%20");
			List<Map<String, Object>> resultListMap = MapUtils.objectsToMaps(resultList);
			List<ExportRetentionVo> list = this.convertListObject(resultListMap);

			ExportAlibabaUtils.exportExcelData(response,sheetName,fileName,req.getColumns(),list,ExportRetentionVo.class);

		} catch (BusinessException e) {
			log.error("export is error", e);
			throw e;
		} catch (Exception e) {
			log.error("export is error", e);
			throw new BusinessException("导出异常");
		}
		return null;
	}

	private List<ExportRetentionVo> convertListObject(List<Map<String, Object>> listMap) {
			for (Map<String, Object> map : listMap) {
				for (Map.Entry<String, Object> entry : map.entrySet()) {
					final String key = entry.getKey();
					final Object value = entry.getValue();

					if (ArrayUtils.contains(RETENTION_KEYS, key)) {
						int num = ObjectUtils.defaultIfNull((BigDecimal) map.get(key + "Num"), BigDecimal.ZERO).intValue();
						if (num > NumberUtils.INTEGER_ZERO) {
						map.put(key, String.format("%s%%(%s人)", BigDecimal.ZERO.equals(value) ? "0.00" : value, map.get(key + "Num")));
						} else {
						map.put(key, String.format("%s%%", BigDecimal.ZERO.equals(value) ? "0.00" : value));
						}
					}

				}

			}

			List<ExportRetentionVo> list= new ArrayList<>();

			JSONArray array = JSONArray.parseArray(JSON.toJSONString(listMap));

			for (int i = 0; i < array.size(); i++) {
				JSONObject jsonObject = array.getJSONObject(i);
				ExportRetentionVo detail = JSON.parseObject(String.valueOf(jsonObject), ExportRetentionVo.class);
				list.add(detail);
			}
			return list;

	}

}
